package com.ysh.spring.aop.service.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 袁胜虎 on 2022/8/28 13:31
 */
@Component
@Aspect//声明这是一个增强类
public class MyAdvice {
    @Pointcut("execution(* com.ysh.spring.aop..*Impl.*(..))")
    public void pointcut(){

    }
    //这是一个前置通知
    //注解的参数就是带有切入点表达式表示的名字
    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        System.err.println("开启事务!!!");
    }
    //代表最终返回 所有的操作都完成后在进行返回 不受异常的影响
    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        System.err.println("after");
    }

    //提交事务应该在AfterReturning中提交
//    AfterReturning的优先级高于After Joinpoint是AOP的连接点。一个连接点代表一个被代理的方法 returning这个参数是指方法中那个参数来接收返回结果
    @AfterReturning(value ="pointcut()",returning = "result")
    public void afterReturn(JoinPoint point,Object result){
        System.err.println("提交事务了!!!MyAdvice中的方法afterReturn执行了!!!"+result);
    }
//    在afterThrowing异常这 添加回滚事务
    @AfterThrowing(value = "pointcut()",throwing = "e")
    public void afterThrowing(JoinPoint point,Exception e){
        System.err.println("MyAdvice中的方法afterThrowing执行了!!!"+e.getMessage());
        System.err.println("回滚事务");
    }

//          环绕通知
    //@Around(value = "pointcut()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint)throws Throwable{
        //环绕通知是自己决定什么时候放行
        System.err.println("环绕通知开始事务");
        //获取返回结果
        Object proceed = joinPoint.proceed();
        System.err.println("环绕通知提交事务");
        //把结果返回 可以自己绝对返回结果
        return proceed;
    }
}